package com.example.zbh.dsliao.ui.activty;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;

import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Environment;
import android.os.PowerManager;
import android.os.SystemClock;
import android.text.TextUtils;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import android.widget.VideoView;

import com.easemob.util.EMLog;
import com.easemob.util.PathUtil;
import com.example.zbh.dsliao.R;
import com.example.zbh.dsliao.utils.DliaoUtils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.List;

/**
 * Created by zbh on 15/11/28.
 */
public class RecorderVideoActivity extends BaseActivity implements View.OnClickListener, SurfaceHolder.Callback, MediaRecorder.OnInfoListener, MediaRecorder.OnErrorListener {
    private PowerManager.WakeLock mWakeLock;
    private static final String CLASS_LABEL = "RecordActivity";
    private ImageView imageStart, imageStop;//开始停止录制
    private MediaRecorder mediaRecorder;
    private VideoView mVideoView;
    private LinearLayout back;
    private String localPath = null;
    private Camera camera;
    //预览宽高
    private int preViewWidth = 480;
    private int preViewHeight = 480;
    private Chronometer chronometer;
    private int frontCamera = 0;//后置摄像头
    private Button btn_switch;
    private android.hardware.Camera.Parameters cameraParameters = null;
    private SurfaceHolder holder;
    private int defaultVideoFrameRate = -1;
    private MediaScannerConnection msc = null;
    private ProgressDialog progressDialog = null;


    @Override
    protected int getLayOut() {
        return R.layout.activity_recorder_video;
    }

    @Override
    protected void initView() {
        btn_switch = findeView(R.id.switch_btn);
        btn_switch.setVisibility(View.VISIBLE);
        mVideoView = findeView(R.id.mVideoView);
        imageStart = findeView(R.id.recorder_start);
        imageStop = findeView(R.id.recorder_stop);
        chronometer = findeView(R.id.chronometer);
        back = findeView(R.id.back);


    }

    @Override
    protected void initData() {
        PowerManager manager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        mWakeLock = manager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, CLASS_LABEL);
        mWakeLock.acquire();
        btn_switch.setOnClickListener(this);
        imageStart.setOnClickListener(this);
        imageStop.setOnClickListener(this);
        back.setOnClickListener(this);
        holder = mVideoView.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.switch_btn:
                switchCamera();
                break;
            case R.id.recorder_start:
                ClickRecorderStart();
                break;
            case R.id.recorder_stop:
                ClickRecorderStop();
                break;
            case R.id.back:
                releaseRecorder();
                releaseCamera();
                finish();
                break;
        }
    }

    private void ClickRecorderStop() {
        imageStop.setEnabled(false);
        // 停止拍摄
        stopRecording();
        btn_switch.setVisibility(View.VISIBLE);
        chronometer.stop();
        imageStart.setVisibility(View.VISIBLE);
        imageStop.setVisibility(View.INVISIBLE);
        new AlertDialog.Builder(this)
                .setMessage("是否发送")
                .setPositiveButton("OK",
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog,
                                                int which) {
                                dialog.dismiss();
                                sendVideo(null);

                            }
                        })
                .setNegativeButton("取消",
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog,
                                                int which) {
                                if(localPath != null){
                                    File file = new File(localPath);
                                    if(file.exists())
                                        file.delete();
                                }
                                finish();

                            }
                        }).setCancelable(false).show();


    }

    private void ClickRecorderStart() {

        if(!startRecording())
            return;
        Toast.makeText(this, "录像开始", Toast.LENGTH_SHORT).show();
        btn_switch.setVisibility(View.INVISIBLE);
        imageStart.setVisibility(View.INVISIBLE);
        imageStart.setEnabled(false);
        imageStop.setVisibility(View.VISIBLE);
        // 重置其他
        chronometer.setBase(SystemClock.elapsedRealtime());
        chronometer.start();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mWakeLock == null) {
            PowerManager manager = (PowerManager) getSystemService(Context.POWER_SERVICE);
            mWakeLock = manager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, CLASS_LABEL);
            mWakeLock.acquire();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseCamera();
        if (mWakeLock != null) {
            mWakeLock.release();
            mWakeLock = null;
        }

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mWakeLock != null) {
            mWakeLock.release();
            mWakeLock = null;
        }
    }

    private boolean initCamera() {
        try {
            if (frontCamera == 0) {
                camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
            } else {
                camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
            }
            Camera.Parameters camPara = camera.getParameters();
            camera.lock();
            holder = mVideoView.getHolder();
            holder.addCallback(this);
            holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            camera.setDisplayOrientation(90);
        } catch (RuntimeException ex) {
            Toast.makeText(this, "开启相机失败", Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;
    }
    //初始化录制
    private boolean initRecorder(){
        if (DliaoUtils.isExitsSdcard()){
            showNoSDCardDialog();
            return false;
        }
        if (camera == null){
            if (!initCamera()){
                showFailDialig();
                return false;
            }
        }
        mVideoView.setVisibility(View.VISIBLE);
        camera.stopPreview();
        mediaRecorder = new MediaRecorder();
        camera.unlock();
        mediaRecorder.setCamera(camera);
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        if (frontCamera == 1){
            mediaRecorder.setOrientationHint(270);
        }else {
            mediaRecorder.setOrientationHint(90);
        }
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mediaRecorder.setVideoSize(preViewWidth, preViewHeight);
        mediaRecorder.setVideoEncodingBitRate(384 * 1024);
        if (defaultVideoFrameRate != -1){
            mediaRecorder.setVideoFrameRate(defaultVideoFrameRate);
        }
        localPath = PathUtil.getInstance().getVideoPath() + "/" + System.currentTimeMillis() + "./mp4";
        mediaRecorder.setOutputFile(localPath);
        mediaRecorder.setMaxDuration(30000);
        mediaRecorder.setPreviewDisplay(holder.getSurface());
        try {
            mediaRecorder.prepare();
        } catch (IllegalStateException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    //停止录制
    public void stopRecording() {
        if (mediaRecorder != null) {
            mediaRecorder.setOnErrorListener(null);
            mediaRecorder.setOnInfoListener(null);
            try {
                mediaRecorder.stop();
            } catch (IllegalStateException e) {
                EMLog.e("video", "stopRecording error:" + e.getMessage());
            }
        }
        releaseRecorder();

        if (camera != null) {
            camera.stopPreview();
            releaseCamera();
        }
    }

    public boolean startRecording(){
        if (mediaRecorder == null){
            if(!initRecorder())
                return false;
        }
        mediaRecorder.setOnInfoListener(this);
        mediaRecorder.setOnErrorListener(this);
        mediaRecorder.start();
        return true;
    }




    public void  sendVideo(View view){
        if (TextUtils.isEmpty(localPath)) {
            EMLog.e("Recorder", "recorder fail please try again!");
            return;
        }
        if(msc == null)
            msc = new MediaScannerConnection(this,
                    new MediaScannerConnection.MediaScannerConnectionClient() {

                        @Override
                        public void onScanCompleted(String path, Uri uri) {

                            msc.disconnect();
                            progressDialog.dismiss();
                            setResult(RESULT_OK, getIntent().putExtra("uri", uri));
                            finish();
                        }

                        @Override
                        public void onMediaScannerConnected() {
                            msc.scanFile(localPath, "video/*");
                        }
                    });


        if(progressDialog == null){
            progressDialog = new ProgressDialog(this);
            progressDialog.setMessage("processing...");
            progressDialog.setCancelable(false);
        }
        progressDialog.show();
        msc.connect();


    }


    private void handleSurfaceChanged() {
        if (camera == null) {
            finish();
            return;
        }
        boolean hasSupportRate = false;
        List<Integer> supportedPreviewFrameRates = camera.getParameters().getSupportedPreviewFrameRates();
        if (supportedPreviewFrameRates != null && supportedPreviewFrameRates.size() > 0) {
            Collections.sort(supportedPreviewFrameRates);
            for (int i = 0; i < supportedPreviewFrameRates.size(); i++) {
                int supportRate = supportedPreviewFrameRates.get(i);
                if (supportRate == 15) {
                    hasSupportRate = true;
                }
            }
            if (hasSupportRate) {
                defaultVideoFrameRate = 15;
            } else {
                defaultVideoFrameRate = supportedPreviewFrameRates.get(0);
            }
        }
        List<Camera.Size> resolutionList = DliaoUtils.getResolutionList(camera);
        if (resolutionList != null && resolutionList.size() > 0) {
            Collections.sort(resolutionList, new DliaoUtils.ResolutionComparator());
            Camera.Size previewSize = null;
            boolean hasSize = false;
            for (int i = 0; i < resolutionList.size(); i++) {
                Camera.Size size = resolutionList.get(i);
                if (size != null && size.width == 640 && size.height == 480) {
                    previewSize = size;
                    preViewWidth = previewSize.width;
                    preViewHeight = previewSize.height;
                    hasSize = true;
                    break;
                }
            }
            if (!hasSize) {
                int mediumResolution = resolutionList.size() / 2;
                if (mediumResolution >= resolutionList.size())
                    mediumResolution = resolutionList.size() - 1;
                previewSize = resolutionList.get(mediumResolution);
                preViewHeight = previewSize.height;
                preViewWidth = previewSize.width;
            }
        }

    }


    private void switchCamera() {
        if (camera == null) {
            return;
        }
        if (Camera.getNumberOfCameras() >= 2) {
            btn_switch.setEnabled(false);
            if (camera != null) {
                camera.stopPreview();
                camera.release();
                camera = null;
            }
            switch (frontCamera) {
                case 0:
                    camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
                    frontCamera = 1;
                    break;
                case 1:
                    camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
                    frontCamera = 0;
                    break;
            }
            try{
                camera.lock();
                camera.setDisplayOrientation(90);
                camera.setPreviewDisplay(mVideoView.getHolder());
                camera.startPreview();
            } catch (IOException e) {
                e.printStackTrace();
            }
            btn_switch.setEnabled(true);
        }
    }


    //释放录制
    private void releaseRecorder() {
        if (mediaRecorder != null) {
            mediaRecorder.release();
            mediaRecorder = null;
        }
    }

    //释放相机
    private void releaseCamera() {
        try {
            if (camera != null) {
                camera.stopPreview();
                camera.release();
                camera = null;
            }
        } catch (Exception e) {

        }
    }
    //保存文件
    public void saveBitmapFile(Bitmap bitmap) {
        File file = new File(Environment.getExternalStorageDirectory(), "a.jpg");
        try {
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(file));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    private void showFailDialig() {
        new AlertDialog.Builder(this)
                .setTitle("提示")
                .setMessage("打开设备失败")
                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                }).setCancelable(false).show();
    }

    private void showNoSDCardDialog() {
        new AlertDialog.Builder(this)
                .setTitle("提示")
                .setMessage("没有sd卡")
                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                }).setCancelable(false).show();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (camera == null){
            if (! initCamera()){
                showFailDialig();
                return;
            }
        }
        try {
            {
                camera.setPreviewDisplay(holder);
                camera.startPreview();
                handleSurfaceChanged();

            }
        } catch (IOException e) {
            e.printStackTrace();
            showFailDialig();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        this.holder = holder;
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }
    @Override
    public void onInfo(MediaRecorder mr, int what, int extra) {
        if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
            stopRecording();
            btn_switch.setVisibility(View.VISIBLE);
            chronometer.stop();
            imageStart.setVisibility(View.VISIBLE);
            imageStop.setVisibility(View.INVISIBLE);
            chronometer.stop();
            if (localPath == null) {
                return;
            }

            new AlertDialog.Builder(this)
                    .setMessage("是否发送")
                    .setPositiveButton("OK",
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface arg0,
                                                    int arg1) {
                                    arg0.dismiss();
                                    sendVideo(null);

                                }
                            }).setNegativeButton("cancle", null)
                    .setCancelable(false).show();
        }
    }


    @Override
    public void onError(MediaRecorder mr, int what, int extra) {
        stopRecording();
        Toast.makeText(this,
                "Recording error has occurred. Stopping the recording",
                Toast.LENGTH_SHORT).show();
    }
}
